# 读Wav文件并且绘制波形
import wave
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示符号

def readWAV(f):
    """读取格式信息
    (声道数、量化位数、采样频率、采样点数、压缩类型、压缩类型的描述)
    """
    file = wave.open(f, "rb")
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = file.getparams()
    nchannels, sampwidth, framerate, nframes = params[:4]
    print(nchannels, sampwidth, framerate, nframes)
    # nchannels通道数 = 2
    # sampwidth量化位数 = 2
    # framerate采样频率 = 48000
    # nframes采样点数 = 499712

    # 读取nframes个数据，返回字符串格式
    str_data = file.readframes(nframes)
    # print("11111", len(str_data))
    file.close()
    return str_data

def wav_to_np(f):
    """ 将字符串转换为数组, 得到一维的short类型的数组"""
    file = wave.open(f, "rb")
    params = file.getparams()
    # nchannels, nframes = params[:2]
    nchannels = params[0]
    nframes = params[3]
    strData = readWAV("luyin.wav")
    # print(strData)
    wave_data = np.frombuffer(strData, dtype=np.short)
    # print(wave_data)

    # 赋值的归一化
    wave_data = wave_data * 1.0 / (max(abs(wave_data)))
    print("len(wave_data)", len(wave_data))

    # 整合左声道和右声道的数据
    wave_data = np.reshape(wave_data, [nframes, nchannels])
    file.close()
    # wave_data.shape = (-1, 2)   # -1的意思就是没有指定,根据另一个维度的数量进行分割
    return wave_data

def frameTime(f):
    """最后通过采样点数和取样频率计算出每个取样的时间"""
    file = wave.open(f, "rb")
    params = file.getparams()
    # framerate, nframes = params[3:4]
    framerate = params[2]
    nframes = params[3]
    time = np.arange(0, nframes) * (1.0 / framerate)
    file.close()
    print("len(time)", len(time))   
    return np.round(time, 5)
 
def writeCSV():
    """生成csv文件"""
    wave_data = wav_to_np("luyin.wav")
    dict_data = {'wave_data1': wave_data[:, 0], 'wave_data2': wave_data[:, 1]}
    dataframe = pd.DataFrame(dict_data, index=list(frameTime("luyin.wav")))
    # dataframe = pd.DataFrame.from_dict({'Time(s)': frameTime(f), 'wave_data1': wave_data[:, 0], 'wave_data2': wave_data[:, 1]},
    #                                    orient='index')
    # invert = dataframe.T
    dataframe.to_csv("wav_to_np.csv", index=True, sep=',')

def pltShow():
    """将读取的wav文件通过采样率绘制波形"""
    wave_data = wav_to_np("hm3/luyin.wav")
    plt.figure()
    # 左声道波形
    plt.subplot(2, 1, 1)
    plt.plot(frameTime("luyin.wav"), wave_data[:, 0])  # wave_data第一列
    plt.xlabel("时间/s", fontsize=14)
    plt.ylabel("幅度", fontsize=14)
    plt.title("左声道", fontsize=14)
    plt.grid()  # 标尺

    plt.subplot(2, 1, 2)
    # 右声道波形
    plt.plot(frameTime("luyin.wav"), wave_data[:, 1], c='g')  # wave_data第二列
    plt.xlabel("时间/s", fontsize=14)
    plt.ylabel("幅度", fontsize=14)
    plt.title("右声道", fontsize=14)

    plt.tight_layout()  # 紧密布局
    plt.show()

if __name__ == '__main__':
    readWAV("luyin.wav")
    wav_to_np("luyin.wav")
    frameTime("luyin.wav")
    writeCSV()
    pltShow()
